import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: xiuwei
 * @version:
 */
@Slf4j
public class RequestControllerManager {

    private static class LazyHolder {
        private static final RequestControllerManager INSTANCE = new RequestControllerManager();
    }

    public static final RequestControllerManager getInstance() {
        return RequestControllerManager.LazyHolder.INSTANCE;
    }

    private RequestControllerManager() {
        init();
    }


    private final Map<String, Map<String, RequestHandler>> requestHandlerMap = new HashMap<>();

    private void addRequestHandler(String requestType, String requestUrl, RequestHandler requestHandler) {
        if (!this.requestHandlerMap.containsKey(requestType)) {
            this.requestHandlerMap.put(requestType, new HashMap<>());
        }
        this.requestHandlerMap.get(requestType).put(requestUrl, requestHandler);
    }
    public RequestHandler getRequestHandler(String requestType, String requestUrl){
        if(this.requestHandlerMap.containsKey(requestType) && this.requestHandlerMap.get(requestType).containsKey(requestUrl)){
            return this.requestHandlerMap.get(requestType).get(requestUrl);
        }else{
            return new RequestHandler() {
                @Override
                public FullHttpResponse handle(FullHttpRequest request) {
                    return getTextResponse("404");
                }
            };
        }
    }

    private void init()  {
        Method[] functions = RequestController.class.getDeclaredMethods();
        for(Method m: functions){
            RequestHandlerFunction t = m.getAnnotation(RequestHandlerFunction.class);
            if(t!=null && m.getReturnType().equals(RequestHandler.class) && m.getParameterCount()==0) {
                try {
                    addRequestHandler(t.requestType().toString(),t.requestUrl(),(RequestHandler)m.invoke(RequestController.getInstance()));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public enum RequestMethodType{
        GET,POST;
        public String toString(){
            switch (this){
                case GET:return "GET";
                case POST: return "POST";
            }
            return "GET";
        }
    }

}
